package org.smog.core.util;

import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.smog.core.function.Consumer_1;
import org.smog.core.function.Function_1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 对象映射转换
 *
 * @Description: Created by IntelliJ IDEA.
 * @project_name: smogTemp
 * @time: 2020-05-14 15:43
 * @email: 17685306043@163.com
 * @author: huangZhongYao
 */
public class AutoMapUtils {
    private static final ModelMapper MODEL_MAPPER;

    static {

        MODEL_MAPPER = new ModelMapper();
        // 设置属性匹配规则,设置为最严格匹配,必须属性名相同
        MODEL_MAPPER.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
    }

    public static <Target> Target map(Object source, Class<Target> targetClass) {
        return source == null ? null : MODEL_MAPPER.map(source, targetClass);
    }

    public static <Target> Target map(Object source, Class<Target> targetClass, Consumer<Target> consumer) {
        Target target = source == null ? null : MODEL_MAPPER.map(source, targetClass);
        if (consumer != null) {
            consumer.accept(target);
        }
        return target;
    }

    public static <TSource, Target> List<Target> mapList(Collection<TSource> sourceList, Class<Target> targetClass, Consumer<Target> consumer) {
        ArrayList<Target> targets = new ArrayList<>();
        if (sourceList == null) {
            return targets;
        }
        sourceList.forEach(p -> {
            Target item = map(p, targetClass);

            if (consumer != null) {
                consumer.accept(item);
            }
            targets.add(item);
        });

        return targets;
    }

    public static <TSource, Target> List<Target> mapList(Collection<TSource> sourceList, Class<Target> targetClass, Consumer_1<TSource, Target> consumer) {
        ArrayList<Target> targets = new ArrayList<>();
        if (sourceList == null) {
            return targets;
        }
        sourceList.forEach(p -> {
            Target item = map(p, targetClass);

            if (consumer != null) {
                consumer.accept(p, item);
            }
            targets.add(item);
        });

        return targets;
    }


    public static <TSource, Target> List<Target> mapList(Collection<TSource> sourceList, Class<Target> targetClass, Function<TSource, Target> fun) {
        ArrayList<Target> targets = new ArrayList<>();
        if (sourceList == null) {
            return targets;
        }
        sourceList.forEach(p -> {
            if (fun != null) {
                targets.add(fun.apply(p));
            }
        });

        return targets;
    }

    public static <TSource, Target> List<Target> mapList(Collection<TSource> sourceList, Class<Target> targetClass, Function_1<TSource, Target> fun) {
        ArrayList<Target> targets = new ArrayList<>();
        if (sourceList == null) {
            return targets;
        }
        sourceList.forEach(p -> {
            Target map = map(p, targetClass);
            if (fun != null) {
                targets.add(fun.apply(p, map));
            }
        });

        return targets;
    }

    public static <TSource, Target> List<Target> mapList(Collection<TSource> sourceList, Class<Target> targetClass) {
        ArrayList<Target> targets = new ArrayList<>();
        if (sourceList == null) {
            return targets;
        }
        sourceList.forEach(p -> {
            Target item = map(p, targetClass);
            targets.add(item);
        });

        return targets;
    }
}
